package com.hwadee.springboot_lx.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hwadee.springboot_lx.entity.Log;
import com.hwadee.springboot_lx.entity.LogSearchCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
public class LogService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    // 初始化 ObjectMapper，配置常规设置
    private final ObjectMapper objectMapper = new ObjectMapper()
//            .findAndAddModules()  // 自动扫描 Java8 日期 API 等模块
            .setDateFormat(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))  // 自定义日期格式
            .configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  // 忽略未知字段

    // 获取日志列表
    public List<Log> getLogs(LogSearchCriteria criteria) {
        // 从 Redis 获取日志数据
        List<String> logsFromRedis = redisTemplate.opsForList().range("logs", 0, -1);

        // 将 Redis 数据转换为 Log 对象并进行过滤
        List<Log> logs = logsFromRedis.stream()
                .map(this::convertToLog) // 使用私有的转换方法
                .filter(log -> log.matches(criteria))  // 假设 Log 类中有 matches 方法
                .collect(Collectors.toList());

        return logs;
    }

    // 排序日志
    public List<Log> sortLogs(String criteria) {
        List<Log> logs = redisTemplate.opsForList().range("logs", 0, -1)
                .stream()
                .map(this::convertToLog)
                .collect(Collectors.toList());

        if ("time".equals(criteria)) {
            logs.sort((log1, log2) -> log1.getTime().compareTo(log2.getTime()));
        } else if ("type".equals(criteria)) {
            logs.sort((log1, log2) -> log1.getLogType().compareTo(log2.getLogType()));
        }
        return logs;
    }

    // 将日志存入 Redis
    public void storeLog(Log log) {
        // 将 Log 对象转为 JSON 字符串
        String logJson = convertLogToJson(log);

        // 将日志存入 Redis 列表
        redisTemplate.opsForList().leftPush("logs", logJson);
    }

    // 导出日志
    public File exportLog(Log log) {
        // 根据日志数据生成 zip 文件
        try {
            // 定义 zip 文件路径
            File file = new File("/path/to/logs/" + log.getId() + ".zip");

            // 创建输出流，写入到文件
            try (FileOutputStream fos = new FileOutputStream(file);
                 ZipOutputStream zos = new ZipOutputStream(fos)) {

                // 创建一个 zip 条目，表示一个文件
                ZipEntry zipEntry = new ZipEntry(log.getId() + ".log");
                zos.putNextEntry(zipEntry);

                // 获取日志内容
                byte[] logContent = log.getDetails().getBytes("UTF-8");

                // 将日志内容写入到 zip 文件中
                zos.write(logContent, 0, logContent.length);

                // 完成 zip 条目
                zos.closeEntry();
            }

            return file;
        } catch (IOException e) {
            throw new RuntimeException("导出日志失败", e);
        }
    }

    // 辅助方法：将 Log 对象转换为 JSON 字符串
    private String convertLogToJson(Log log) {
        try {
            return objectMapper.writeValueAsString(log);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换日志为 JSON 失败", e);
        }
    }

    // 辅助方法：将 JSON 字符串转换为 Log 对象
    private Log convertToLog(String logJson) {
        try {
            return objectMapper.readValue(logJson, Log.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换 JSON 为日志失败", e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
